home *** CD-ROM | disk | FTP | other *** search
/ Millennium Gold 2000 / Millennium Gold 2000 - Disc 1.iso / GNUCHESS / EVAL.C < prev    next >
C/C++ Source or Header  |  1995-07-27  |  35KB  |  1,341 lines

  1. /*
  2.   C source for GNU CHESS
  3.  
  4.   Revision: 1990-09-30
  5.  
  6.   Modified by Daryl Baker for use in MS WINDOWS environment
  7.  
  8.   Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
  9.   Copyright (c) 1988, 1989, 1990  John Stanback
  10.  
  11.   This file is part of CHESS.
  12.  
  13.   CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
  14.   WARRANTY.  No author or distributor accepts responsibility to anyone for
  15.   the consequences of using it or for whether it serves any particular
  16.   purpose or works at all, unless he says so in writing.  Refer to the CHESS
  17.   General Public License for full details.
  18.  
  19.   Everyone is granted permission to copy, modify and redistribute CHESS, but
  20.   only under the conditions described in the CHESS General Public License.
  21.   A copy of this license is supposed to have been given to you along with
  22.   CHESS so you can know your rights and responsibilities.  It should be in a
  23.   file named COPYING.  Among other things, the copyright notice and this
  24.   notice must be preserved on all copies.
  25. */
  26.  
  27. #define NOATOM 
  28. #define NOCLIPBOARD
  29. #define NOCREATESTRUCT
  30. #define NOFONT
  31. #define NOREGION
  32. #define NOSOUND
  33. #define NOWH
  34. #define NOWINOFFSETS
  35. #define NOCOMM
  36. #define NOKANJI
  37.  
  38. #include <windows.h>
  39. #include <stdio.h>
  40.  
  41. #include "gnuchess.h"
  42. #include "defs.h"
  43.  
  44. #ifdef WIN32
  45. #define _BASEETC
  46. #else
  47. #define _BASEETC _based(_segname("_CODE")) 
  48. #endif
  49.  
  50. /*#define taxicab(a,b) taxidata[a][b]*/
  51. #define taxicab(a,b) *(taxidata+a*64+b)
  52.  
  53. #define wking PieceList[white][0]
  54. #define bking PieceList[black][0]
  55. #define EnemyKing PieceList[c2][0]
  56.  
  57. /*extern short distdata[64][64], taxidata[64][64];*/
  58. extern short far *distdata, far *taxidata;
  59.  
  60. /*extern unsigned char nextpos[8][64][64];*/
  61. /*extern unsigned char nextdir[8][64][64];*/
  62. extern unsigned char far * nextpos;
  63. extern unsigned char far * nextdir;
  64.  
  65.  
  66. extern short PieceList[2][16], PawnCnt[2][8];
  67. extern short Pscore[maxdepth], Tscore[maxdepth];
  68. extern short mtl[2], pmtl[2], emtl[2], hung[2];
  69. extern short c1, c2, *atk1, *atk2, *PC1, *PC2, atak[2][64];
  70. extern short ChkFlag[maxdepth], CptrFlag[maxdepth], PawnThreat[maxdepth];
  71. extern short Pindex[64];
  72. extern short PieceCnt[2];
  73. extern short FROMsquare, TOsquare, Zscore, zwndw;
  74. extern short Mking[2][64], Kfield[2][64];
  75. extern short ATAKD, HUNGP, HUNGX, KCASTLD, KMOVD, XRAY, PINVAL;
  76. extern short RHOPN, RHOPNX, KHOPN, KHOPNX, KSFTY;
  77. extern short HasKnight[2], HasBishop[2], HasRook[2], HasQueen[2];
  78. extern short Mwpawn[64], Mbpawn[64], Mknight[2][64], Mbishop[2][64];
  79. extern short Mking[2][64], Kfield[2][64];
  80. extern short KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  81. extern short PEDRNK2B, PWEAKH, PADVNCM, PADVNCI, PAWNSHIELD, PDOUBLED, PBLOK;
  82. extern short stage, stage2, Developed[2];
  83. extern short PawnBonus, BishopBonus, RookBonus;
  84.  
  85.  
  86. static short _BASEETC KingOpening[64] =
  87. {0, 0, -4, -10, -10, -4, 0, 0,
  88.  -4, -4, -8, -12, -12, -8, -4, -4,
  89.  -12, -16, -20, -20, -20, -20, -16, -12,
  90.  -16, -20, -24, -24, -24, -24, -20, -16,
  91.  -16, -20, -24, -24, -24, -24, -20, -16,
  92.  -12, -16, -20, -20, -20, -20, -16, -12,
  93.  -4, -4, -8, -12, -12, -8, -4, -4,
  94.  0, 0, -4, -10, -10, -4, 0, 0};
  95.  
  96. static short _BASEETC KingEnding[64] =
  97. {0, 6, 12, 18, 18, 12, 6, 0,
  98.  6, 12, 18, 24, 24, 18, 12, 6,
  99.  12, 18, 24, 30, 30, 24, 18, 12,
  100.  18, 24, 30, 36, 36, 30, 24, 18,
  101.  18, 24, 30, 36, 36, 30, 24, 18,
  102.  12, 18, 24, 30, 30, 24, 18, 12,
  103.  6, 12, 18, 24, 24, 18, 12, 6,
  104.  0, 6, 12, 18, 18, 12, 6, 0};
  105.  
  106. static short _BASEETC DyingKing[64] =
  107. {0, 8, 16, 24, 24, 16, 8, 0,
  108.  8, 32, 40, 48, 48, 40, 32, 8,
  109.  16, 40, 56, 64, 64, 56, 40, 16,
  110.  24, 48, 64, 72, 72, 64, 48, 24,
  111.  24, 48, 64, 72, 72, 64, 48, 24,
  112.  16, 40, 56, 64, 64, 56, 40, 16,
  113.  8, 32, 40, 48, 48, 40, 32, 8,
  114.  0, 8, 16, 24, 24, 16, 8, 0};
  115.  
  116. static short _BASEETC KBNK[64] =
  117. {99, 90, 80, 70, 60, 50, 40, 40,
  118.  90, 80, 60, 50, 40, 30, 20, 40,
  119.  80, 60, 40, 30, 20, 10, 30, 50,
  120.  70, 50, 30, 10, 0, 20, 40, 60,
  121.  60, 40, 20, 0, 10, 30, 50, 70,
  122.  50, 30, 10, 20, 30, 40, 60, 80,
  123.  40, 20, 30, 40, 50, 60, 80, 90,
  124.  40, 40, 50, 60, 70, 80, 90, 99};
  125.  
  126. static short _BASEETC pknight[64] =
  127. {0, 4, 8, 10, 10, 8, 4, 0,
  128.  4, 8, 16, 20, 20, 16, 8, 4,
  129.  8, 16, 24, 28, 28, 24, 16, 8,
  130.  10, 20, 28, 32, 32, 28, 20, 10,
  131.  10, 20, 28, 32, 32, 28, 20, 10,
  132.  8, 16, 24, 28, 28, 24, 16, 8,
  133.  4, 8, 16, 20, 20, 16, 8, 4,
  134.  0, 4, 8, 10, 10, 8, 4, 0};
  135.  
  136. static short _BASEETC pbishop[64] =
  137. {14, 14, 14, 14, 14, 14, 14, 14,
  138.  14, 22, 18, 18, 18, 18, 22, 14,
  139.  14, 18, 22, 22, 22, 22, 18, 14,
  140.  14, 18, 22, 22, 22, 22, 18, 14,
  141.  14, 18, 22, 22, 22, 22, 18, 14,
  142.  14, 18, 22, 22, 22, 22, 18, 14,
  143.  14, 22, 18, 18, 18, 18, 22, 14,
  144.  14, 14, 14, 14, 14, 14, 14, 14};
  145.  
  146. static short _BASEETC  PawnAdvance[64] =
  147. {0, 0, 0, 0, 0, 0, 0, 0,
  148.  4, 4, 4, 0, 0, 4, 4, 4,
  149.  6, 8, 2, 10, 10, 2, 8, 6,
  150.  6, 8, 12, 16, 16, 12, 8, 6,
  151.  8, 12, 16, 24, 24, 16, 12, 8,
  152.  12, 16, 24, 32, 32, 24, 16, 12,
  153.  12, 16, 24, 32, 32, 24, 16, 12,
  154.  0, 0, 0, 0, 0, 0, 0, 0};
  155.  
  156. static short _BASEETC value[7] =
  157. {0, valueP, valueN, valueB, valueR, valueQ, valueK};
  158.  
  159. static short _BASEETC control[7] =
  160. {0, ctlP, ctlN, ctlB, ctlR, ctlQ, ctlK};
  161.  
  162. static short _BASEETC PassedPawn0[8] =
  163. {0, 60, 80, 120, 200, 360, 600, 800};
  164.  
  165. static short _BASEETC PassedPawn1[8] =
  166. {0, 30, 40, 60, 100, 180, 300, 800};
  167.  
  168. static short _BASEETC PassedPawn2[8] =
  169. {0, 15, 25, 35, 50, 90, 140, 800};
  170.  
  171. static short _BASEETC PassedPawn3[8] =
  172. {0, 5, 10, 15, 20, 30, 140, 800};
  173.  
  174. static short _BASEETC ISOLANI[8] =
  175. {-12, -16, -20, -24, -24, -20, -16, -12};
  176.  
  177. static short _BASEETC BACKWARD[16] =
  178. {-6, -10, -15, -21, -28, -28, -28, -28,
  179.  -28, -28, -28, -28, -28, -28, -28, -28};
  180.  
  181. static short _BASEETC BMBLTY[14] =
  182. {-2, 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16, 16, 16};
  183.  
  184. static short _BASEETC RMBLTY[15] =
  185. {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14};
  186.  
  187. static short _BASEETC KTHRT[36] =
  188. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  189.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  190.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  191.  
  192. /*
  193.   ptype is used to separate white and black pawns, like this;
  194.   ptyp = ptype[side][piece]
  195.   piece can be used directly in nextpos/nextdir when generating moves
  196.   for pieces that are not black pawns.
  197. */
  198. static short _BASEETC ptype[2][8] =
  199. {
  200.   no_piece, pawn, knight, bishop, rook, queen, king, no_piece,
  201.   no_piece, bpawn, knight, bishop, rook, queen, king, no_piece};
  202.  
  203. static short _BASEETC direc[8][8] =
  204. {
  205.   0, 0, 0, 0, 0, 0, 0, 0,
  206.   10, 9, 11, 0, 0, 0, 0, 0,
  207.   8, -8, 12, -12, 19, -19, 21, -21,
  208.   9, 11, -9, -11, 0, 0, 0, 0,
  209.   1, 10, -1, -10, 0, 0, 0, 0,
  210.   1, 10, -1, -10, 9, 11, -9, -11,
  211.   1, 10, -1, -10, 9, 11, -9, -11,
  212.   -10, -9, -11, 0, 0, 0, 0, 0};
  213.  
  214. static short _BASEETC max_steps[8] =
  215. {0, 2, 1, 7, 7, 7, 1, 2};
  216.  
  217. static short _BASEETC nunmap[120] =
  218. {
  219.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  220.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  221.   -1, 0, 1, 2, 3, 4, 5, 6, 7, -1,
  222.   -1, 8, 9, 10, 11, 12, 13, 14, 15, -1,
  223.   -1, 16, 17, 18, 19, 20, 21, 22, 23, -1,
  224.   -1, 24, 25, 26, 27, 28, 29, 30, 31, -1,
  225.   -1, 32, 33, 34, 35, 36, 37, 38, 39, -1,
  226.   -1, 40, 41, 42, 43, 44, 45, 46, 47, -1,
  227.   -1, 48, 49, 50, 51, 52, 53, 54, 55, -1,
  228.   -1, 56, 57, 58, 59, 60, 61, 62, 63, -1,
  229.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  230.   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
  231.  
  232. static short _BASEETC qrook[3] = {0, 56, 0};
  233.  
  234. static short _BASEETC krook[3] = {7, 63, 0};
  235.  
  236. static short _BASEETC kingP[3] = {4, 60, 0};
  237.  
  238. static short _BASEETC rank7[3] = {6, 1, 0};
  239.  
  240. static short _BASEETC sweep[8] =
  241. {false, false, false, true, true, true, false, false};
  242.  
  243.  
  244. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  245.  
  246. int
  247. evaluate (short int side,
  248.           short int ply,
  249.           short int alpha,
  250.           short int beta,
  251.           short int INCscore,
  252.           short int *slk,
  253.           short int *InChk)
  254.  
  255. /*
  256.   Compute an estimate of the score by adding the positional score from the
  257.   previous ply to the material difference. If this score falls inside a
  258.   window which is 180 points wider than the alpha-beta window (or within a
  259.   50 point window during quiescence search) call ScorePosition() to
  260.   determine a score, otherwise return the estimated score. If one side has
  261.   only a king and the other either has no pawns or no pieces then the
  262.   function ScoreLoneKing() is called.
  263. */
  264.  
  265. {
  266.   register short evflag, xside;
  267.   short s;
  268.  
  269.   xside = otherside[side];
  270.   s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  271.   hung[white] = hung[black] = 0;
  272.   *slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  273.          (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  274.  
  275.   if (*slk)
  276.     evflag = false;
  277.   else
  278.     evflag =
  279.       (ply == 1 || ply < Sdepth ||
  280.        ((ply == Sdepth + 1 || ply == Sdepth + 2) &&
  281.         (s > alpha - xwndw && s < beta + xwndw)) ||
  282.        (ply > Sdepth + 2 && s >= alpha - 25 && s <= beta + 25));
  283.  
  284.   if (evflag)
  285.     {
  286.       EvalNodes++;
  287.       ataks (side, atak[side]);
  288.       if (Anyatak (side, PieceList[xside][0]))
  289.         return (10001 - ply);
  290.       ataks (xside, atak[xside]);
  291.       *InChk = Anyatak (xside, PieceList[side][0]);
  292.       ScorePosition (side, &s);
  293.     }
  294.   else
  295.     {
  296.       if (SqAtakd (PieceList[xside][0], side))
  297.         return (10001 - ply);
  298.       *InChk = SqAtakd (PieceList[side][0], xside);
  299.       if (*slk)
  300.         ScoreLoneKing (side, &s);
  301.     }
  302.  
  303.   Pscore[ply] = s - mtl[side] + mtl[xside];
  304.   if (*InChk)
  305.     ChkFlag[ply - 1] = Pindex[TOsquare];
  306.   else
  307.     ChkFlag[ply - 1] = 0;
  308.   return (s);
  309. }
  310.  
  311.  
  312. static inline int
  313. ScoreKPK (short int side,
  314.           short int winner,
  315.           short int loser,
  316.           short int king1,
  317.           short int king2,
  318.           short int sq)
  319.  
  320. /*
  321.   Score King and Pawns versus King endings.
  322. */
  323.  
  324. {
  325.   register short s, r;
  326.  
  327.   if (PieceCnt[winner] == 1)
  328.     s = 50;
  329.   else
  330.     s = 120;
  331.   if (winner == white)
  332.     {
  333.       if (side == loser)
  334.         r = row (sq) - 1;
  335.       else
  336.         r = row (sq);
  337.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  338.         s += 10 * row (sq);
  339.       else
  340.         s = 500 + 50 * row (sq);
  341.       if (row (sq) < 6)
  342.         sq += 16;
  343.       else
  344.         if (row(sq) == 6)
  345.           sq += 8;
  346.     }
  347.   else
  348.     {
  349.       if (side == loser)
  350.         r = row (sq) + 1;
  351.       else
  352.         r = row (sq);
  353.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  354.         s += 10 * (7 - row (sq));
  355.       else
  356.         s = 500 + 50 * (7 - row (sq));
  357.       if (row (sq) > 1)
  358.         sq -= 16;
  359.       else
  360.         if (row(sq) == 1)
  361.           sq -= 8;
  362.     }
  363.   s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  364.   return (s);
  365. }
  366.  
  367.  
  368. static inline int
  369. ScoreKBNK (short int winner, short int king1, short int king2)
  370.  
  371.  
  372. /*
  373.   Score King+Bishop+Knight versus King endings.
  374.   This doesn't work all that well but it's better than nothing.
  375. */
  376.  
  377. {
  378.   register short s, sq, KBNKsq = 0;
  379.  
  380.   for (sq = 0; sq < 64; sq++)
  381.     if (board[sq] == bishop)
  382.       if (row (sq) % 2 == column (sq) % 2)
  383.         KBNKsq = 0;
  384.       else
  385.         KBNKsq = 7;
  386.  
  387.   s = emtl[winner] - 300;
  388.   if (KBNKsq == 0)
  389.     s += KBNK[king2];
  390.   else
  391.     s += KBNK[locn (row (king2), 7 - column (king2))];
  392.   s -= taxicab (king1, king2);
  393.   s -= distance (PieceList[winner][1], king2);
  394.   s -= distance (PieceList[winner][2], king2);
  395.   return (s);
  396. }
  397.  
  398.  
  399. void
  400. ScoreLoneKing (short int side, short int *score)
  401.  
  402. /*
  403.   Static evaluation when loser has only a king and winner has no pawns or no
  404.   pieces.
  405. */
  406.  
  407. {
  408.   register short winner, loser, king1, king2, s, i;
  409.  
  410.   UpdateWeights ();
  411.   if (mtl[white] > mtl[black])
  412.     winner = white;
  413.   else
  414.     winner = black;
  415.   loser = otherside[winner];
  416.   king1 = PieceList[winner][0];
  417.   king2 = PieceList[loser][0];
  418.  
  419.   s = 0;
  420.  
  421.   if (pmtl[winner] > 0)
  422.     for (i = 1; i <= PieceCnt[winner]; i++)
  423.       s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  424.  
  425.   else if (emtl[winner] == valueB + valueN)
  426.     s = ScoreKBNK (winner, king1, king2);
  427.  
  428.   else if (emtl[winner] > valueB)
  429.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  430.  
  431.   if (side == winner)
  432.     *score = s;
  433.   else
  434.     *score = -s;
  435. }
  436.  
  437.  
  438. static inline void
  439. BRscan (short int sq, short int *s, short int *mob)
  440.  
  441. /*
  442.   Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  443.   hung[] array if a pin is found.
  444. */
  445. {
  446.   register short u, piece, pin;
  447.   unsigned char far *ppos, far *pdir;
  448.   short *Kf;
  449.  
  450.   Kf = Kfield[c1];
  451.   *mob = 0;
  452.   piece = board[sq];
  453.   ppos = nextpos+piece*64*64+sq*64;
  454.   pdir = nextdir+piece*64*64+sq*64;
  455.   u = ppos[sq];
  456.   pin = -1;                     /* start new direction */
  457.   do
  458.     {
  459.       *s += Kf[u];
  460.       if (color[u] == neutral)
  461.         {
  462.           (*mob)++;
  463.           if (ppos[u] == pdir[u])
  464.             pin = -1;           /* oops new direction */
  465.           u = ppos[u];
  466.         }
  467.       else if (pin < 0)
  468.         {
  469.           if (board[u] == pawn || board[u] == king)
  470.             u = pdir[u];
  471.           else
  472.             {
  473.               if (ppos[u] != pdir[u])
  474.                 pin = u;        /* not on the edge and on to find a pin */
  475.               u = ppos[u];
  476.             }
  477.         }
  478.       else
  479.         {
  480.           if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  481.             {
  482.               if (color[pin] == c2)
  483.                 {
  484.                   *s += PINVAL;
  485.                   if (atk2[pin] == 0 ||
  486.                       atk1[pin] > control[board[pin]] + 1)
  487.                     ++hung[c2];
  488.                 }
  489.               else
  490.                 *s += XRAY;
  491.             }
  492.           pin = -1;             /* new direction */
  493.           u = pdir[u];
  494.         }
  495.   } while (u != sq);
  496. }
  497.  
  498.  
  499. static inline void
  500. KingScan (short int sq, short int *s)
  501.  
  502. /*
  503.   Assign penalties if king can be threatened by checks, if squares
  504.   near the king are controlled by the enemy (especially the queen),
  505.   or if there are no pawns near the king.
  506.   The following must be true:
  507.   board[sq] == king
  508.   c1 == color[sq]
  509.   c2 == otherside[c1]
  510. */
  511.  
  512. #define ScoreThreat \
  513. if (color[u] != c2)\
  514.   if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  515.   else *s -= 3
  516.  
  517. {
  518.   register short u;
  519.   register unsigned char far *ppos, far *pdir;
  520.   register short cnt, ok;
  521.  
  522.   cnt = 0;
  523.   if (HasBishop[c2] || HasQueen[c2])
  524.     {
  525.       ppos = nextpos+bishop*64*64+sq*64;
  526.       pdir = nextdir+bishop*64*64+sq*64;
  527.       u = ppos[sq];
  528.       do
  529.         {
  530.           if (atk2[u] & ctlBQ)
  531.             ScoreThreat;
  532.           u = (color[u] == neutral) ? ppos[u] : pdir[u];
  533.       } while (u != sq);
  534.     }
  535.   if (HasRook[c2] || HasQueen[c2])
  536.     {
  537.       ppos = nextpos+rook*64*64+sq*64;
  538.       pdir = nextdir+rook*64*64+sq*64;
  539.       u = ppos[sq];
  540.       do
  541.         {
  542.           if (atk2[u] & ctlRQ)
  543.             ScoreThreat;
  544.           u = (color[u] == neutral) ? ppos[u] : pdir[u];
  545.       } while (u != sq);
  546.     }
  547.   if (HasKnight[c2])
  548.     {
  549.       pdir = nextdir+knight*64*64+sq*64;
  550.       u = pdir[sq];
  551.       do
  552.         {
  553.           if (atk2[u] & ctlNN)
  554.             ScoreThreat;
  555.           u = pdir[u];
  556.       } while (u != sq);
  557.     }
  558.   *s += (KSFTY * KTHRT[cnt]) / 16;
  559.  
  560.   cnt = 0;
  561.   ok = false;
  562.   pdir = nextpos+king*64*64+sq*64;
  563.   u = pdir[sq];
  564.   do
  565.     {
  566.       if (board[u] == pawn)
  567.         ok = true;
  568.       if (atk2[u] > atk1[u])
  569.         {
  570.           ++cnt;
  571.           if (atk2[u] & ctlQ)
  572.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  573.               *s -= 4 * KSFTY;
  574.         }
  575.       u = pdir[u];
  576.   } while (u != sq);
  577.   if (!ok)
  578.     *s -= KSFTY;
  579.   if (cnt > 1)
  580.     *s -= KSFTY;
  581. }
  582.  
  583.  
  584. static inline int
  585. trapped (short int sq)
  586.  
  587. /*
  588.   See if the attacked piece has unattacked squares to move to.
  589.   The following must be true:
  590.   c1 == color[sq]
  591.   c2 == otherside[c1]
  592. */
  593.  
  594. {
  595.   register short u, piece;
  596.   register unsigned char far *ppos, far *pdir;
  597.  
  598.   piece = board[sq];
  599.   ppos = nextpos+(ptype[c1][piece]*64*64)+sq*64;
  600.   pdir = nextdir+(ptype[c1][piece]*64*64)+sq*64;
  601.   if (piece == pawn)
  602.     {
  603.       u = ppos[sq];     /* follow no captures thread */
  604.       if (color[u] == neutral)
  605.         {
  606.           if (atk1[u] >= atk2[u])
  607.             return (false);
  608.           if (atk2[u] < ctlP)
  609.             {
  610.               u = ppos[u];
  611.               if (color[u] == neutral && atk1[u] >= atk2[u])
  612.                 return (false);
  613.             }
  614.         }
  615.       u = pdir[sq];     /* follow captures thread */
  616.       if (color[u] == c2)
  617.         return (false);
  618.       u = pdir[u];
  619.       if (color[u] == c2)
  620.         return (false);
  621.     }
  622.   else
  623.     {
  624.       u = ppos[sq];
  625.       do
  626.         {
  627.           if (color[u] != c1)
  628.             if (atk2[u] == 0 || board[u] >= piece)
  629.               return (false);
  630.           u = (color[u] == neutral) ? ppos[u] : pdir[u];
  631.       } while (u != sq);
  632.     }
  633.   return (true);
  634. }
  635.  
  636.  
  637. static inline int
  638. PawnValue (short int sq, short int side)
  639.  
  640. /*
  641.   Calculate the positional value for a pawn on 'sq'.
  642. */
  643.  
  644. {
  645.   register short j, fyle, rank;
  646.   register short s, a1, a2, in_square, r, e;
  647.  
  648.   a1 = (atk1[sq] & 0x4FFF);
  649.   a2 = (atk2[sq] & 0x4FFF);
  650.   rank = row (sq);
  651.   fyle = column (sq);
  652.   s = 0;
  653.   if (c1 == white)
  654.     {
  655.       s = Mwpawn[sq];
  656.       if ((sq == 11 && color[19] != neutral)
  657.           || (sq == 12 && color[20] != neutral))
  658.         s += PEDRNK2B;
  659.       if ((fyle == 0 || PC1[fyle - 1] == 0)
  660.           && (fyle == 7 || PC1[fyle + 1] == 0))
  661.         s += ISOLANI[fyle];
  662.       else if (PC1[fyle] > 1)
  663.         s += PDOUBLED;
  664.       if (a1 < ctlP && atk1[sq + 8] < ctlP)
  665.         {
  666.           s += BACKWARD[a2 & 0xFF];
  667.           if (PC2[fyle] == 0)
  668.             s += PWEAKH;
  669.           if (color[sq + 8] != neutral)
  670.             s += PBLOK;
  671.         }
  672.       if (PC2[fyle] == 0)
  673.         {
  674.           if (side == black)
  675.             r = rank - 1;
  676.           else
  677.             r = rank;
  678.           in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  679.           if (a2 == 0 || side == white)
  680.             e = 0;
  681.           else
  682.             e = 1;
  683.           for (j = sq + 8; j < 64; j += 8)
  684.             if (atk2[j] >= ctlP)
  685.               {
  686.                 e = 2;
  687.                 break;
  688.               }
  689.             else if (atk2[j] > 0 || color[j] != neutral)
  690.               e = 1;
  691.           if (e == 2)
  692.             s += (stage * PassedPawn3[rank]) / 10;
  693.           else if (in_square || e == 1)
  694.             s += (stage * PassedPawn2[rank]) / 10;
  695.           else if (emtl[black] > 0)
  696.             s += (stage * PassedPawn1[rank]) / 10;
  697.           else
  698.             s += PassedPawn0[rank];
  699.         }
  700.     }
  701.   else if (c1 == black)
  702.     {
  703.       s = Mbpawn[sq];
  704.       if ((sq == 51 && color[43] != neutral)
  705.           || (sq == 52 && color[44] != neutral))
  706.         s += PEDRNK2B;
  707.       if ((fyle == 0 || PC1[fyle - 1] == 0) &&
  708.           (fyle == 7 || PC1[fyle + 1] == 0))
  709.         s += ISOLANI[fyle];
  710.       else if (PC1[fyle] > 1)
  711.         s += PDOUBLED;
  712.       if (a1 < ctlP && atk1[sq - 8] < ctlP)
  713.         {
  714.           s += BACKWARD[a2 & 0xFF];
  715.           if (PC2[fyle] == 0)
  716.             s += PWEAKH;
  717.           if (color[sq - 8] != neutral)
  718.             s += PBLOK;
  719.         }
  720.       if (PC2[fyle] == 0)
  721.         {
  722.           if (side == white)
  723.             r = rank + 1;
  724.           else
  725.             r = rank;
  726.           in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  727.           if (a2 == 0 || side == black)
  728.             e = 0;
  729.           else
  730.             e = 1;
  731.           for (j = sq - 8; j >= 0; j -= 8)
  732.             if (atk2[j] >= ctlP)
  733.               {
  734.                 e = 2;
  735.                 break;
  736.               }
  737.             else if (atk2[j] > 0 || color[j] != neutral)
  738.               e = 1;
  739.           if (e == 2)
  740.             s += (stage * PassedPawn3[7 - rank]) / 10;
  741.           else if (in_square || e == 1)
  742.             s += (stage * PassedPawn2[7 - rank]) / 10;
  743.           else if (emtl[white] > 0)
  744.             s += (stage * PassedPawn1[7 - rank]) / 10;
  745.           else
  746.             s += PassedPawn0[7 - rank];
  747.         }
  748.     }
  749.   if (a2 > 0)
  750.     {
  751.       if (a1 == 0 || a2 > ctlP + 1)
  752.         {
  753.           s += HUNGP;
  754.           ++hung[c1];
  755.           if (trapped (sq))
  756.             ++hung[c1];
  757.         }
  758.       else
  759.         if (a2 > a1)
  760.           s += ATAKD;
  761.     }
  762.   return (s);
  763. }
  764.  
  765.  
  766. static inline int
  767. KnightValue (short int sq, short int side)
  768.  
  769. /*
  770.   Calculate the positional value for a knight on 'sq'.
  771. */
  772.  
  773. {
  774.   register short s, a2, a1;
  775.  
  776.   s = Mknight[c1][sq];
  777.   a2 = (atk2[sq] & 0x4FFF);
  778.   if (a2 > 0)
  779.     {
  780.       a1 = (atk1[sq] & 0x4FFF);
  781.       if (a1 == 0 || a2 > ctlBN + 1)
  782.         {
  783.           s += HUNGP;
  784.           ++hung[c1];
  785.           if (trapped (sq))
  786.             ++hung[c1];
  787.         }
  788.       else
  789.         if (a2 >= ctlBN || a1 < ctlP)
  790.           s += ATAKD;
  791.     }
  792.   return (s);
  793. }
  794.  
  795.  
  796. static inline int
  797. BishopValue (short int sq, short int side)
  798.  
  799. /*
  800.   Calculate the positional value for a bishop on 'sq'.
  801. */
  802.  
  803. {
  804.   register short a2, a1;
  805.   short s, mob;
  806.  
  807.   s = Mbishop[c1][sq];
  808.   BRscan (sq, &s, &mob);
  809.   s += BMBLTY[mob];
  810.   a2 = (atk2[sq] & 0x4FFF);
  811.   if (a2 > 0)
  812.     {
  813.       a1 = (atk1[sq] & 0x4FFF);
  814.       if (a1 == 0 || a2 > ctlBN + 1)
  815.         {
  816.           s += HUNGP;
  817.           ++hung[c1];
  818.           if (trapped (sq))
  819.             ++hung[c1];
  820.         }
  821.       else
  822.         if (a2 >= ctlBN || a1 < ctlP)
  823.           s += ATAKD;
  824.     }
  825.   return (s);
  826. }
  827.  
  828.  
  829. static inline int
  830. RookValue (short int sq, short int side)
  831.  
  832. /*
  833.   Calculate the positional value for a rook on 'sq'.
  834. */
  835.  
  836. {
  837.   register short fyle, a2, a1;
  838.   short s, mob;
  839.  
  840.   s = RookBonus;
  841.   BRscan (sq, &s, &mob);
  842.   s += RMBLTY[mob];
  843.   fyle = column (sq);
  844.   if (PC1[fyle] == 0)
  845.     s += RHOPN;
  846.   if (PC2[fyle] == 0)
  847.     s += RHOPNX;
  848.   if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  849.     s += 10;
  850.   if (stage > 2)
  851.     s += 14 - taxicab (sq, EnemyKing);
  852.   a2 = (atk2[sq] & 0x4FFF);
  853.   if (a2 > 0)
  854.     {
  855.       a1 = (atk1[sq] & 0x4FFF);
  856.       if (a1 == 0 || a2 > ctlR + 1)
  857.         {
  858.           s += HUNGP;
  859.           ++hung[c1];
  860.  
  861.           if (trapped (sq))
  862.             ++hung[c1];
  863.         }
  864.       else
  865.         if (a2 >= ctlR || a1 < ctlP)
  866.           s += ATAKD;
  867.     }
  868.   return (s);
  869. }
  870.  
  871.  
  872. static inline int
  873. QueenValue (short int sq, short int side)
  874.  
  875. /*
  876.   Calculate the positional value for a queen on 'sq'.
  877. */
  878.  
  879. {
  880.   register short s, a2, a1;
  881.  
  882.   s = (distance (sq, EnemyKing) < 3) ? 12 : 0;
  883.   if (stage > 2)
  884.     s += 14 - taxicab (sq, EnemyKing);
  885.   a2 = (atk2[sq] & 0x4FFF);
  886.   if (a2 > 0)
  887.     {
  888.       a1 = (atk1[sq] & 0x4FFF);
  889.       if (a1 == 0 || a2 > ctlQ + 1)
  890.         {
  891.           s += HUNGP;
  892.           ++hung[c1];
  893.           if (trapped (sq))
  894.             ++hung[c1];
  895.         }
  896.       else
  897.         if (a2 >= ctlQ || a1 < ctlP)
  898.           s += ATAKD;
  899.     }
  900.   return (s);
  901. }
  902.  
  903.  
  904. static inline int
  905. KingValue (short int sq, short int side)
  906.  
  907. /*
  908.   Calculate the positional value for a king on 'sq'.
  909. */
  910.  
  911. {
  912.   register short fyle, a2, a1;
  913.   short s;
  914.  
  915.   s = Mking[c1][sq];
  916.   if (KSFTY > 0)
  917.     if (Developed[c2] || stage > 0)
  918.       KingScan (sq, &s);
  919.   if (castld[c1])
  920.     s += KCASTLD;
  921.   else if (Mvboard[kingP[c1]])
  922.     s += KMOVD;
  923.  
  924.   fyle = column (sq);
  925.   if (PC1[fyle] == 0)
  926.     s += KHOPN;
  927.   if (PC2[fyle] == 0)
  928.     s += KHOPNX;
  929.   switch (fyle)
  930.     {
  931.     case 5:
  932.       if (PC1[7] == 0)
  933.         s += KHOPN;
  934.       if (PC2[7] == 0)
  935.         s += KHOPNX;
  936.       /* Fall through */
  937.     case 4:
  938.     case 6:
  939.     case 0:
  940.       if (PC1[fyle + 1] == 0)
  941.         s += KHOPN;
  942.       if (PC2[fyle + 1] == 0)
  943.         s += KHOPNX;
  944.       break;
  945.     case 2:     
  946.       if (PC1[0] == 0)
  947.         s += KHOPN;
  948.       if (PC2[0] == 0)
  949.         s += KHOPNX;
  950.       /* Fall through */
  951.     case 3:
  952.     case 1:
  953.     case 7:  
  954.       if (PC1[fyle - 1] == 0)
  955.         s += KHOPN;
  956.       if (PC2[fyle - 1] == 0)
  957.         s += KHOPNX;
  958.       break;
  959.     default:
  960.       /* Impossible! */
  961.       break;
  962.     }
  963.  
  964.   a2 = (atk2[sq] & 0x4FFF);
  965.   if (a2 > 0)
  966.     {
  967.       a1 = (atk1[sq] & 0x4FFF);
  968.       if (a1 == 0 || a2 > ctlK + 1)
  969.         {
  970.           s += HUNGP;
  971.           ++hung[c1];
  972.         }
  973.       else
  974.         s += ATAKD;
  975.     }
  976.   return (s);
  977. }
  978.  
  979.  
  980. void
  981. ScorePosition (short int side, short int *score)
  982.  
  983. /*
  984.   Perform normal static evaluation of board position. A score is generated
  985.   for each piece and these are summed to get a score for each side.
  986. */
  987.  
  988. {
  989.   register short sq, s, i, xside;
  990.   short pscore[2];
  991.  
  992.   UpdateWeights ();
  993.   xside = otherside[side];
  994.   pscore[white] = pscore[black] = 0;
  995.  
  996.   for (c1 = white; c1 <= black; c1++)
  997.     {
  998.       c2 = otherside[c1];
  999.       atk1 = atak[c1];
  1000.       atk2 = atak[c2];
  1001.       PC1 = PawnCnt[c1];
  1002.       PC2 = PawnCnt[c2];
  1003.       for (i = PieceCnt[c1]; i >= 0; i--)
  1004.         {
  1005.           sq = PieceList[c1][i];
  1006.           switch (board[sq])
  1007.             {
  1008.             case pawn:
  1009.               s = PawnValue(sq, side);
  1010.               break;
  1011.             case knight:
  1012.               s = KnightValue(sq, side);
  1013.               break;
  1014.             case bishop:
  1015.               s = BishopValue(sq, side);
  1016.               break;
  1017.             case rook:
  1018.               s = RookValue(sq, side);
  1019.               break;
  1020.             case queen:
  1021.               s = QueenValue(sq, side);
  1022.               break;
  1023.             case king:
  1024.               s = KingValue(sq, side);
  1025.               break;
  1026.             default:
  1027.               s = 0;
  1028.               break;
  1029.             }
  1030.           pscore[c1] += s;
  1031.           svalue[sq] = s;
  1032.         }
  1033.     }
  1034.   if (hung[side] > 1)
  1035.     pscore[side] += HUNGX;
  1036.   if (hung[xside] > 1)
  1037.     pscore[xside] += HUNGX;
  1038.  
  1039.   *score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  1040.   if (dither)
  1041.     *score += urand () % dither;
  1042.  
  1043.   if (*score > 0 && pmtl[side] == 0)
  1044.     if (emtl[side] < valueR)
  1045.       *score = 0;
  1046.     else if (*score < valueR)
  1047.       *score /= 2;
  1048.   if (*score < 0 && pmtl[xside] == 0)
  1049.     if (emtl[xside] < valueR)
  1050.       *score = 0;
  1051.     else if (-*score < valueR)
  1052.       *score /= 2;
  1053.  
  1054.   if (mtl[xside] == valueK && emtl[side] > valueB)
  1055.     *score += 200;
  1056.   if (mtl[side] == valueK && emtl[xside] > valueB)
  1057.     *score -= 200;
  1058. }
  1059.  
  1060.  
  1061. static inline void
  1062. BlendBoard (const short int far  a[64], const short int far b[64], short int c[64])
  1063. {
  1064.   register int sq;
  1065.  
  1066.   for (sq = 0; sq < 64; sq++)
  1067.     c[sq] = (a[sq] * (10 - stage) + b[sq] * stage) / 10;
  1068. }
  1069.  
  1070.  
  1071. static inline void
  1072. CopyBoard (const short int far a[64], short int b[64])
  1073. {
  1074.   register int sq;
  1075.  
  1076.   for (sq = 0; sq < 64; sq++)
  1077.     b[sq] = a[sq];
  1078. }
  1079.  
  1080. void
  1081. ExaminePosition (void)
  1082.  
  1083. /*
  1084.   This is done one time before the search is started. Set up arrays
  1085.   Mwpawn, Mbpawn, Mknight, Mbishop, Mking which are used in the
  1086.   SqValue() function to determine the positional value of each piece.
  1087. */
  1088.  
  1089. {
  1090.   register short i, sq;
  1091.   short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, fyle, rank;
  1092.   static short PawnStorm = false;
  1093.  
  1094.   ataks (white, atak[white]);
  1095.   ataks (black, atak[black]);
  1096.   UpdateWeights ();
  1097.   HasKnight[white] = HasKnight[black] = 0;
  1098.   HasBishop[white] = HasBishop[black] = 0;
  1099.   HasRook[white] = HasRook[black] = 0;
  1100.   HasQueen[white] = HasQueen[black] = 0;
  1101.   for (side = white; side <= black; side++)
  1102.     for (i = PieceCnt[side]; i >= 0; i--)
  1103.       switch (board[PieceList[side][i]])
  1104.         {
  1105.         case knight:
  1106.           ++HasKnight[side];
  1107.           break;
  1108.         case bishop:
  1109.           ++HasBishop[side];
  1110.           break;
  1111.         case rook:
  1112.           ++HasRook[side];
  1113.           break;
  1114.         case queen:
  1115.           ++HasQueen[side];
  1116.           break;
  1117.         }
  1118.   if (!Developed[white])
  1119.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  1120.                         board[5] != bishop && board[6] != knight);
  1121.   if (!Developed[black])
  1122.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  1123.                         board[61] != bishop && board[62] != knight);
  1124.   if (!PawnStorm && stage < 5)
  1125.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  1126.                  (column (wking) > 4 && column (bking) < 3));
  1127.  
  1128.   CopyBoard (pknight, Mknight[white]);
  1129.   CopyBoard (pknight, Mknight[black]);
  1130.   CopyBoard (pbishop, Mbishop[white]);
  1131.   CopyBoard (pbishop, Mbishop[black]);
  1132.   BlendBoard (KingOpening, KingEnding, Mking[white]);
  1133.   BlendBoard (KingOpening, KingEnding, Mking[black]);
  1134.  
  1135.   for (sq = 0; sq < 64; sq++)
  1136.     {
  1137.       fyle = column (sq);
  1138.       rank = row (sq);
  1139.       wstrong = bstrong = true;
  1140.       for (i = sq; i < 64; i += 8)
  1141.         if (Patak (black, i))
  1142.           {
  1143.             wstrong = false;
  1144.             break;
  1145.           }
  1146.       for (i = sq; i >= 0; i -= 8)
  1147.         if (Patak (white, i))
  1148.           {
  1149.             bstrong = false;
  1150.             break;
  1151.           }
  1152.       wpadv = bpadv = PADVNCM;
  1153.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) &&
  1154.           (fyle == 7 || PawnCnt[white][fyle + 1] == 0))
  1155.         wpadv = PADVNCI;
  1156.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) &&
  1157.           (fyle == 7 || PawnCnt[black][fyle + 1] == 0))
  1158.         bpadv = PADVNCI;
  1159.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  1160.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  1161.       Mwpawn[sq] += PawnBonus;
  1162.       Mbpawn[sq] += PawnBonus;
  1163.       if (Mvboard[kingP[white]])
  1164.         {
  1165.           if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  1166.             Mwpawn[sq] += PAWNSHIELD;
  1167.         }
  1168.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  1169.         Mwpawn[sq] += PAWNSHIELD / 2;
  1170.       if (Mvboard[kingP[black]])
  1171.         {
  1172.           if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  1173.             Mbpawn[sq] += PAWNSHIELD;
  1174.         }
  1175.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  1176.         Mbpawn[sq] += PAWNSHIELD / 2;
  1177.       if (PawnStorm)
  1178.         {
  1179.           if ((column (wking) < 4 && fyle > 4) ||
  1180.               (column (wking) > 3 && fyle < 3))
  1181.             Mwpawn[sq] += 3 * rank - 21;
  1182.           if ((column (bking) < 4 && fyle > 4) ||
  1183.               (column (bking) > 3 && fyle < 3))
  1184.             Mbpawn[sq] -= 3 * rank;
  1185.         }
  1186.       Mknight[white][sq] += 5 - distance (sq, bking);
  1187.       Mknight[white][sq] += 5 - distance (sq, wking);
  1188.       Mknight[black][sq] += 5 - distance (sq, wking);
  1189.       Mknight[black][sq] += 5 - distance (sq, bking);
  1190.       Mbishop[white][sq] += BishopBonus;
  1191.       Mbishop[black][sq] += BishopBonus;
  1192.    {
  1193.       int xxxtmp;
  1194.  
  1195.       for (i = PieceCnt[black]; i >= 0; i--) {
  1196.          xxxtmp = PieceList[black][i];
  1197.         if (distance (sq, xxxtmp) < 3)
  1198.           Mknight[white][sq] += KNIGHTPOST;
  1199.       }
  1200.       for (i = PieceCnt[white]; i >= 0; i--) {
  1201.          xxxtmp = PieceList[white][i];
  1202.         if (distance (sq, xxxtmp) < 3)
  1203.           Mknight[black][sq] += KNIGHTPOST;
  1204.       }
  1205.    }
  1206.       if (wstrong)
  1207.         Mknight[white][sq] += KNIGHTSTRONG;
  1208.       if (bstrong)
  1209.         Mknight[black][sq] += KNIGHTSTRONG;
  1210.       if (wstrong)
  1211.         Mbishop[white][sq] += BISHOPSTRONG;
  1212.       if (bstrong)
  1213.         Mbishop[black][sq] += BISHOPSTRONG;
  1214.  
  1215.       if (HasBishop[white] == 2)
  1216.         Mbishop[white][sq] += 8;
  1217.       if (HasBishop[black] == 2)
  1218.         Mbishop[black][sq] += 8;
  1219.       if (HasKnight[white] == 2)
  1220.         Mknight[white][sq] += 5;
  1221.       if (HasKnight[black] == 2)
  1222.         Mknight[black][sq] += 5;
  1223.  
  1224.       Kfield[white][sq] = Kfield[black][sq] = 0;
  1225.       if (distance (sq, wking) == 1)
  1226.         Kfield[black][sq] = KATAK;
  1227.       if (distance (sq, bking) == 1)
  1228.         Kfield[white][sq] = KATAK;
  1229.  
  1230.       Pd = 0;
  1231.       for (k = 0; k <= PieceCnt[white]; k++)
  1232.         {
  1233.           i = PieceList[white][k];
  1234.           if (board[i] == pawn)
  1235.             {
  1236.               pp = true;
  1237.               if (row (i) == 6)
  1238.                 z = i + 8;
  1239.               else
  1240.                 z = i + 16;
  1241.               for (j = i + 8; j < 64; j += 8)
  1242.                 if (Patak (black, j) || board[j] == pawn)
  1243.                   {
  1244.                     pp = false;
  1245.                     break;
  1246.                   }
  1247.               if (pp)
  1248.                 Pd += 5 * taxicab (sq, z);
  1249.               else
  1250.                 Pd += taxicab (sq, z);
  1251.             }
  1252.         }
  1253.       for (k = 0; k <= PieceCnt[black]; k++)
  1254.         {
  1255.           i = PieceList[black][k];
  1256.           if (board[i] == pawn)
  1257.             {
  1258.               pp = true;
  1259.               if (row (i) == 1)
  1260.                 z = i - 8;
  1261.               else
  1262.                 z = i - 16;
  1263.               for (j = i - 8; j >= 0; j -= 8)
  1264.                 if (Patak (white, j) || board[j] == pawn)
  1265.                   {
  1266.                     pp = false;
  1267.                     break;
  1268.                   }
  1269.               if (pp)
  1270.                 Pd += 5 * taxicab (sq, z);
  1271.               else
  1272.                 Pd += taxicab (sq, z);
  1273.             }
  1274.         }
  1275.       if (Pd != 0)
  1276.         {
  1277.           val = (Pd * stage2) / 10;
  1278.           Mking[white][sq] -= val;
  1279.           Mking[black][sq] -= val;
  1280.         }
  1281.     }
  1282. }
  1283.  
  1284. void
  1285. UpdateWeights (void)
  1286.  
  1287. /*
  1288.   If material balance has changed, determine the values for the positional
  1289.   evaluation terms.
  1290. */
  1291.  
  1292. {
  1293.   register short tmtl, s1;
  1294.  
  1295.   emtl[white] = mtl[white] - pmtl[white] - valueK;
  1296.   emtl[black] = mtl[black] - pmtl[black] - valueK;
  1297.   tmtl = emtl[white] + emtl[black];
  1298.   s1 = (tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520);
  1299.   if (s1 != stage)
  1300.     {
  1301.       stage = s1;
  1302.       stage2 = (tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220);
  1303.       PEDRNK2B = -15;   /* centre pawn on 2nd rank & blocked */
  1304.       PBLOK = -4;               /* blocked backward pawn */
  1305.       PDOUBLED = -14;   /* doubled pawn */
  1306.       PWEAKH = -4;              /* weak pawn on half open file */
  1307.       PAWNSHIELD = 10 - stage;  /* pawn near friendly king */
  1308.       PADVNCM = 10;             /* advanced pawn multiplier */
  1309.       PADVNCI = 7;              /* muliplier for isolated pawn */
  1310.       PawnBonus = stage;
  1311.       
  1312.       KNIGHTPOST = (stage + 2) / 3;     /* knight near enemy pieces */
  1313.       KNIGHTSTRONG = (stage + 6) / 2;   /* occupies pawn hole */
  1314.       
  1315.       BISHOPSTRONG = (stage + 6) / 2;   /* occupies pawn hole */
  1316.       BishopBonus = 2 * stage;
  1317.       
  1318.       RHOPN = 10;               /* rook on half open file */
  1319.       RHOPNX = 4;
  1320.       RookBonus = 6 * stage;
  1321.       
  1322.       XRAY = 8;         /* Xray attack on piece */
  1323.       PINVAL = 10;              /* Pin */
  1324.       
  1325.       KHOPN = (3 * stage - 30) / 2;     /* king on half open file */
  1326.       KHOPNX = KHOPN / 2;
  1327.       KCASTLD = 10 - stage;
  1328.       KMOVD = -40 / (stage + 1);        /* king moved before castling */
  1329.       KATAK = (10 - stage) / 2; /* B,R attacks near enemy king */
  1330.       if (stage < 8)
  1331.         KSFTY = 16 - 2 * stage;
  1332.       else
  1333.         KSFTY = 0;
  1334.       
  1335.       ATAKD = -6;               /* defender > attacker */
  1336.       HUNGP = -8;               /* each hung piece */
  1337.       HUNGX = -12;              /* extra for >1 hung piece */
  1338.     }
  1339. }
  1340.  
  1341.